package com.zgjkhis.modules.statistics.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zgjkhis.common.service.impl.BaseServiceImpl;
import com.zgjkhis.modules.enums.DrugTypeEnum;
import com.zgjkhis.modules.statistics.domain.DrugStatistics;
import com.zgjkhis.modules.statistics.domain.PigeonholeParam;
import com.zgjkhis.modules.statistics.req.StoreDrugRequest;
import com.zgjkhis.modules.statistics.resp.DrugStatisticsDto;
import com.zgjkhis.modules.statistics.resp.DrugStatisticsSum;
import com.zgjkhis.modules.statistics.resp.StoreDrugResp;
import com.zgjkhis.modules.statistics.service.StoreDrugService;
import com.zgjkhis.modules.statistics.service.mapper.StoreDrugMapper;
import com.zgjkhis.modules.system.domain.Drug;
import com.zgjkhis.modules.util.CharUtil;
import com.zgjkhis.utils.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

/**
 * 运营数据：药房药品
 * @Author yxl
 * @Description
 * @Date 2021/12/23 17:49
 **/
@Service
@Slf4j
public class StoreDrugServiceImpl extends BaseServiceImpl<StoreDrugMapper, DrugStatistics> implements StoreDrugService {

    @Override
    public StoreDrugResp findStatistics(StoreDrugRequest request) {
//        if(request.getType() == 0) {
//            return this.findSynAll(request);
//        }
        return this.findAll(request);
    }

    /**
     * 实时统计
     * @return
     */
    private StoreDrugResp findSynAll(StoreDrugRequest request) {
        StoreDrugResp resp = new StoreDrugResp();

        // 查询药品
        DrugStatisticsSum statisticsSum = new DrugStatisticsSum();
        List<Drug> list = this.baseMapper.findDrug(request);
        List<DrugStatisticsDto> listDto = new ArrayList<>();
        int total = this.baseMapper.findDrugCount(request);

        if(total > 0) {
            list.forEach(item -> {
                // 药品销量，销售额，利润、成本价
                DrugStatisticsDto s = this.baseMapper.findDrugStatistics(request, item.getId());
                setDrugStatistics(listDto, item, s);
            });

            // 总计
//            DrugStatisticsDto statistics = this.baseMapper.findDrugStatistics(request, null);
            setStatisticsSum(statisticsSum, null);
        } else {
            statisticsSum.setPrice(BigDecimal.ZERO);
            statisticsSum.setProfit(BigDecimal.ZERO);
            statisticsSum.setCostPrice(BigDecimal.ZERO);
        }

        resp.setContent(listDto);
        resp.setStatisticsSum(statisticsSum);
        resp.setTotalElements(total);
        return resp;
    }

    /**
     * 设置药品销量，销售额，利润、成本价
     * @param statisticsSum
     * @param statistics
     */
    private void setStatisticsSum(DrugStatisticsSum statisticsSum, DrugStatisticsDto statistics) {
        if(statistics != null) {
            statisticsSum.setCostPrice(statistics.getCostPrice());
            statisticsSum.setPrice(statistics.getPrice());
            statisticsSum.setProfit(statistics.getProfit());
            statisticsSum.setCostPrice(statistics.getCostPrice());
        }  else {
            statisticsSum.setPrice(BigDecimal.ZERO);
            statisticsSum.setProfit(BigDecimal.ZERO);
            statisticsSum.setCostPrice(BigDecimal.ZERO);
        }
    }

    /**
     * 归档记录
     * @param request
     * @return
     */
    private StoreDrugResp findAll(StoreDrugRequest request) {
        // 查询药品
        DrugStatisticsSum statisticsSum = new DrugStatisticsSum();
        List<Drug> list = this.baseMapper.findDrug(request);
        List<DrugStatisticsDto> listDto = new ArrayList<>();
        int total = this.baseMapper.findDrugCount(request);

        if(total > 0) {
            list.forEach(item -> {
                // 药品销量，销售额，利润，均成本
                DrugStatisticsDto s = this.baseMapper.findPigeonhole(request, item.getId());
                setDrugStatistics(listDto, item, s);
            });

            // 总计
            DrugStatisticsDto statistics = this.baseMapper.findPigeonholeSum(request);
            setStatisticsSum(statisticsSum, statistics);
        } else {
            statisticsSum.setPrice(BigDecimal.ZERO);
            statisticsSum.setProfit(BigDecimal.ZERO);
            statisticsSum.setCostPrice(BigDecimal.ZERO);
        }

        StoreDrugResp resp = new StoreDrugResp();
        resp.setContent(listDto);
        resp.setStatisticsSum(statisticsSum);
        resp.setTotalElements(total);
        return resp;
    }

    /**
     * 设置药品销量，销售额，利润，成本
     * @param listDto
     * @param item
     * @param s
     */
    private void setDrugStatistics(List<DrugStatisticsDto> listDto, Drug item, DrugStatisticsDto s) {
        if (s == null) {
            s = new DrugStatisticsDto();
            s.setProfit(BigDecimal.ZERO);
            s.setPrice(BigDecimal.ZERO);
            s.setCostPrice(BigDecimal.ZERO);
            s.setQuantity(0);
        }
        s.copy(item);
        s.setDrugId(item.getId());
        listDto.add(s);
    }

    @Override
    public void dayPigeonhole(String date) {
        if(date == null || date.isEmpty()) {
            DateTime dateTime = DateUtil.offset(new Date(), DateField.DAY_OF_MONTH, -7);
            date = DateUtil.formatDate(dateTime);
        }
        Date pigeonholeTime = DateUtil.parseDate(date);
        // 清理当天的归档记录
        this.clearPigeonhole(pigeonholeTime);

        // 开始归档
        PigeonholeParam param = new PigeonholeParam(date + " 00:00:00", date + " 23:59:59");

        if(this.count() == 0) {
            // 初次运行
            param.setStartTime(null);
        }

        List<DrugStatistics> statisticsList = this.baseMapper.findDrugPigeonhole(param);
        if(statisticsList == null || statisticsList.isEmpty()) {return;}
        statisticsList.forEach(item -> {
            item.setCreateTime(new Date());
            this.save(item);
        });
    }
    @Override
    public void dayPigeonholeForTask(String date) {
        List<DrugStatistics> drugStatistics = this.baseMapper.selectList(Wrappers.<DrugStatistics>query().lambda().orderByDesc(DrugStatistics::getPigeonholeTime).last("limit 0,1"));
        String startTime=DateUtil.formatDate(new Date());
        if(!CharUtil.isEmpty(drugStatistics)){
            Date pigeonholeTime = drugStatistics.get(0).getPigeonholeTime();
            DateTime offset = DateUtil.offset(pigeonholeTime, DateField.DAY_OF_MONTH, 1);
            startTime=DateUtil.formatDate(offset);
        }
        log.info("开始时间：{}",startTime);
        //今天时间
        date = DateUtil.formatDate(new Date());
        Date pigeonholeTime = DateUtil.parseDate(date);

        // 开始归档
        PigeonholeParam param = new PigeonholeParam(date + " 00:00:00", date + " 00:00:00");

        param.setStartTime(startTime+" 00:00:00");
        log.info("时间{}~{}",param.getStartTime(),param.getEndTime());
        // 清理当天的归档记录
        this.clearPigeonhole(DateUtil.parseDate(param.getStartTime()));
        List<DrugStatistics> statisticsList = this.baseMapper.findDrugPigeonhole(param);
        if(statisticsList == null || statisticsList.isEmpty()) {return;}
        statisticsList.forEach(item -> {
            item.setCreateTime(new Date());
            this.save(item);
        });
    }

    /**
     * 清理归档记录
     * 出错自动修复
     * @param pigeonholeTime
     */
    private void clearPigeonhole(Date pigeonholeTime) {
        LambdaQueryWrapper<DrugStatistics> wrapper =  Wrappers.lambdaQuery();
        wrapper.gt(DrugStatistics::getPigeonholeTime, pigeonholeTime);
        this.remove(wrapper);
    }

    @Override
    public void export(StoreDrugRequest request, HttpServletResponse response) throws IOException {
        StoreDrugResp resp;
//        if(request.getType() == 0) {
//            resp = this.findSynAll(request);
//        } else {
            resp = this.findAll(request);
//        }
        List<Map<String, Object>> list = new ArrayList<>();
        for (DrugStatisticsDto dto : resp.getContent()) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("药品编码", dto.getDrugId());
            map.put("药品名称", dto.getDrugName());
            map.put("药品分类", DrugTypeEnum.findByCode(dto.getDrugType()));
            map.put("销量", dto.getQuantity());
            map.put("销售额", dto.getPrice());
            map.put("成本", dto.getCostPrice());
            map.put("利润", dto.getProfit());
            list.add(map);
        }
        Map<String, Object> map = new LinkedHashMap<>();
        DrugStatisticsSum statisticsSum = resp.getStatisticsSum();
        map.put("药品编码", "/");
        map.put("药品名称", "总计");
        map.put("药品分类", "");
        map.put("销量", "");
        map.put("销售额", statisticsSum.getPrice());
        map.put("成本", statisticsSum.getCostPrice());
        map.put("利润", statisticsSum.getProfit());
        list.add(map);
        FileUtil.downloadExcel(list, response);
    }
}
